<template>
  <el-tabs v-model="selTabId" @tab-click="tabClick">
    <el-tab-pane v-for="item in courseTab" :key="item.courseId"
                 :label="item.courseName" :name="String(item.courseId)">
      <el-card style="margin-bottom: 10px">
        <el-form ref="form" label-width="80px">
          <el-form-item v-for="(item,index) in examCourseData" :key="index" :label="getExamTypeDict(item.examType)">
            <el-row>
              <el-col :span="6">
                <el-input type="number" placeholder="优秀分数" v-model="item.excellentScore" :disabled="editScoreFlag">
                  <template slot="prepend">优秀分数</template>
                </el-input>
              </el-col>
              <el-col :span="6" :offset="3">
                <el-input type="number" placeholder="良好分数" v-model="item.goodScore" :disabled="editScoreFlag">
                  <template slot="prepend">良好分数</template>
                </el-input>
              </el-col>
              <el-col :span="6" :offset="3">
                <el-input type="number" placeholder="及格分数" v-model="item.passScore" :disabled="editScoreFlag">
                  <template slot="prepend">及格分数</template>
                </el-input>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item style="text-align: center" label-width="0">
            <el-button type="primary" icon="el-icon-edit" @click="toggleEditScoreFlag">修改</el-button>
            <el-button type="success" icon="el-icon-receiving" @click="editExamCourse">保存</el-button>
          </el-form-item>
        </el-form>
      </el-card>

      <el-card>
        <!--搜索-->
        <el-form :model="queryParams" ref="queryForm" :inline="true">
          <el-form-item label="姓名" prop="studentName">
            <el-input v-model="queryParams.studentName" placeholder="请输入学生姓名"
                      clearable size="small" @keyup.enter.native="getExamCourseScore"/>
          </el-form-item>
          <el-form-item label="考试类型" prop="examType">
            <el-select v-model="queryParams.examType" placeholder="请选择" clearable size="small">
              <el-option v-for="item in examTypeOpt" :key="item.dictValue" :value="item.dictValue" :label="item.dictLabel"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" icon="el-icon-search" size="mini" @click="getExamCourseScore">搜索</el-button>
            <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
          </el-form-item>
        </el-form>

        <el-row :gutter="10" class="mb8">
          <el-col :span="1.5">
            <el-button type="primary" icon="el-icon-edit" size="mini"
                       @click="toggleExamScoreFlag">修改</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="success" icon="el-icon-receiving" size="mini"
                       @click="courseScoreSubmit" :loading="submitLoading">保存</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="warning" icon="el-icon-upload2" size="mini"
                       @click="uploadScore">导入</el-button>
          </el-col>
          <el-col :span="1.5">
            <el-button type="info" icon="el-icon-download" size="mini"
                       @click="exportTable(item.courseName)">导出</el-button>
          </el-col>
        </el-row>

        <el-table :data="courseScoreData" :span-method="objectSpanMethod" v-loading="loading" height="500px" ref="table">
          <el-table-column label="学号" align="center" prop="studentNo"/>
          <el-table-column label="姓名" align="center" prop="studentName"/>
          <el-table-column label="考试类型" align="center" prop="examType" :formatter="examTypeFormat"/>
          <el-table-column label="是否缺考" align="center" prop="missExam" width="150px">
            <template v-slot="scope">
              <el-radio-group v-model="scope.row.missExam" @change="handleMissExamChange(scope.row)">
                <el-radio :label="false" :disabled="examScoreFlag">否</el-radio>
                <el-radio :label="true" :disabled="examScoreFlag">是</el-radio>
              </el-radio-group>
            </template>
          </el-table-column>
          <el-table-column label="缺考说明" align="center" prop="missExamDesc">
            <template v-slot="scope">
              <el-input v-model="scope.row.missExamDesc" placeholder="缺考说明" :disabled="!scope.row.missExam || examScoreFlag"></el-input>
            </template>
          </el-table-column>
          <el-table-column label="考试分数" align="center" prop="score">
            <template v-slot="scope">
              <span v-if="examScoreFlag">{{scope.row.score}}</span>
              <el-input v-else type="number" v-model="scope.row.score" placeholder="分数" min="0" max="100"
                        :disabled="scope.row.missExam" @input="validateScore(scope.row)"></el-input>
            </template>
          </el-table-column>
          <el-table-column label="成绩等级" align="center" prop="scoreGrade">
            <template v-slot="scope">
              <el-tag v-if="scope.row.score >= scope.row.excellentScore" type="success">优秀</el-tag>
              <el-tag v-else-if="scope.row.score >= scope.row.goodScore">良好</el-tag>
              <el-tag v-else-if="scope.row.score >= scope.row.passScore" type="warning">及格</el-tag>
              <el-tag v-else type="danger">不及格</el-tag>
            </template>
          </el-table-column>
          <el-table-column label="总成绩" align="center" prop="totalScore"/>
          <el-table-column label="是否通过" align="center" prop="isPassed">
            <template v-slot="scope">
              <el-tag :type="scope.row.isPassed ? 'success' : 'danger'">
                {{ scope.row.isPassed ? '通过' : '未通过' }}
              </el-tag>
            </template>
          </el-table-column>
        </el-table>
      </el-card>

    </el-tab-pane>

    <el-dialog title="成绩导入" :visible.sync="uploadDialog" width="400px" append-to-body>
      <el-upload ref="upload" :limit="1" drag
        accept=".xlsx, .xls" action="" :auto-upload="false">
        <i class="el-icon-upload" />
        <div class="el-upload__text">
          将文件拖到此处，或
          <em>点击上传</em>
        </div>
        <div class="el-upload__tip" slot="tip">
          <el-link type="info" style="font-size: 12px" @click="exportTable(selTabName)">下载模板</el-link>
        </div>
        <div class="el-upload__tip" style="color: red" slot="tip">
          <p>1 请先下载模板，根据模板进行导入</p>
          <p>2 模板中</p>
          <p style="padding-left: 10px">2.1 学号,姓名,考试类型字段勿动</p>
          <p style="padding-left: 10px">2.2 是否缺考字段请填写是或者否</p>
          <p style="padding-left: 10px">2.3 缺考说明,考试分数字段用户自行填写</p>
          <p style="padding-left: 10px">2.4 成绩等级,总成绩,是否通过字段不用处理,系统会根据填入的分数,自动判断</p>
          <p>3 导入后,确定无误请点击保存按钮进行成绩保存</p>
        </div>
      </el-upload>
      <div slot="footer" class="dialog-footer">
        <el-button type="warning" @click="submitFileForm">导 入</el-button>
        <el-button @click="uploadDialog = false">取 消</el-button>
      </div>
    </el-dialog>
  </el-tabs>
</template>


<script>
import { getExamCourseTab, getExamCourseScore, enterExamCourseStudentScore, editExamCourse } from '@/api/exam/exam'

export default {
  name: "editExamScore",
  props: ["examId", "classId", "courseType"],
  data() {
    return {
      examTypeOpt: [], //考试类型字典数据
      spanMap: null, // 用于存储学号及其对应的起始行和合并行数的map
      loading: false, //表格遮罩层
      submitLoading: false, //按钮遮罩层
      queryParams: { //考试课程table查询参数
        studentName: '',
        examType : '',
      },
      editScoreFlag: true, //修改分数等级禁用
      examScoreFlag: true, //学生分数录入禁用

      courseTab: [], //考试课程tab
      selTabId: '', //选中的tab id
      selTabName: '', //选中的tab name

      courseScoreData: [], //考试课程成绩table数据列表
      examCourseData: [], //考试课程信息数据列表

      uploadDialog : false , //导入对话框显示状态
      importFile: null, // 用于存储导入文件的变量
    }
  },
  created() {
    //获取考试类型字典数据
    this.getDicts("exam_type").then(response => {
      this.examTypeOpt = response.data;
    })
    //根据课程类型获取该考试下的考试科目
    getExamCourseTab(this.examId, this.courseType).then(res => {
      if (!Array.isArray(res.data) || res.data.length === 0) {
        console.warn('课程标签数据为空');
        return;
      }
      this.courseTab = res.data;
      const firstCourse = this.courseTab[0];
      this.selTabId = firstCourse ? String(firstCourse.courseId) : '';
      this.selTabName = firstCourse ? firstCourse.courseName : '';
      this.getExamCourseScore();
    })
    .catch(error => {
      // 处理请求失败的情况
      console.error('获取课程标签失败:', error);
    });
  },
  methods: {
    //tab切换事件
    tabClick(tab, event) {
      this.queryParams.studentName = '';
      this.selTabId = tab.name;
      this.selTabName = tab.label;
      this.getExamCourseScore();
    },
    //考试类型字典回显处理
    examTypeFormat(row) {
      return this.getExamTypeDict(row.examType)
    },
    // 获取考试类型字典label数据
    getExamTypeDict(examType) {
      return this.selectDictLabel(this.examTypeOpt, examType)
    },
    //成绩分数等级修改解禁
    toggleEditScoreFlag() {
      this.editScoreFlag = !this.editScoreFlag;
    },
    //学生成绩分数录入解禁
    toggleExamScoreFlag() {
      this.examScoreFlag = !this.examScoreFlag;
    },
    //修改考试课程信息
    editExamCourse() {
      // 验证逻辑
      const errors = [];

      const isValid = this.examCourseData.every(course => {
        const hasEmptyField = ['excellentScore', 'goodScore', 'passScore'].some(
          key => !course[key] || isNaN(Number(course[key]))
        );

        if (hasEmptyField) {
          errors.push('优秀成绩、良好成绩和及格成绩不能为空');
          return false;
        }

        const scoreValues = {
          excellent: Number(course.excellentScore),
          good: Number(course.goodScore),
          pass: Number(course.passScore)
        };

        if (scoreValues.excellent <= scoreValues.good) {
          errors.push('优秀成绩需大于良好成绩');
          return false;
        }

        if (scoreValues.good <= scoreValues.pass) {
          errors.push('良好成绩需大于及格成绩');
          return false;
        }

        return true;
      });

      if (!isValid) {
        this.$message.error(errors.join('；'));
        return;
      }

      // 提交数据
      editExamCourse(this.examCourseData).then(() => {
        this.$message.success('保存成功！');
        this.editScoreFlag = true;
        this.getExamCourseScore();
      }).catch(error => {
        this.$message.error('保存失败，请重试');
        console.error('保存失败:', error);
      });
    },
    //根据考试id,班级id,课程id获取成绩记录
    getExamCourseScore() {
      this.spanMap = null;
      this.loading = true;
      getExamCourseScore(this.classId, this.examId, parseInt(this.selTabId), this.queryParams).then(res => {
        this.loading = false;
        this.courseScoreData = res.data.map(item => ({
          ...item,
          missExam: item.missExam || false,
          totalScore: 0, // 初始化总成绩
          scoreGrade: '',// 初始化成绩等级
        }));
        this.calculateTotalScore(); // 计算总成绩
        this.getExamCourseData(res.data); //获取考试课程信息
        this.courseScoreData.sort((a, b) => a.totalScore - b.totalScore); // 修改排序为正序
        this.calculateSpanMap(); // 重新计算合并行数
      }).catch(err => {
        console.log("err", err);
        this.loading = false;
      })
    },
    //重置搜索
    resetQuery() {
      this.queryParams.studentName = '';
      this.queryParams.examType = '';
      this.getExamCourseScore();
    },
    // 计算总成绩
    calculateTotalScore() {
      const studentScores = {};
      this.courseScoreData.forEach(item => {
        if (!studentScores[item.studentNo]) {
          studentScores[item.studentNo] = {
            totalScore: 0,
            isPassed: true // 初始化为通过
          };
        }
        studentScores[item.studentNo].totalScore += item.score || 0;
        if (item.score < item.passScore) {
          studentScores[item.studentNo].isPassed = false; // 如果有一门不及格，则未通过
        }
      });
      this.courseScoreData.forEach(item => {
        item.totalScore = studentScores[item.studentNo].totalScore;
        item.isPassed = studentScores[item.studentNo].isPassed;
      });
    },
    //课程信息获取
    getExamCourseData(res) {
      if (!Array.isArray(res)) {
        console.error('传入的数据不是数组');
        return;
      }
      if (res.length === 0) {
        this.examCourseData = [];
        return;
      }

      const groupedData = res.reduce((accumulator, currentItem) => {
        const key = currentItem.examCourseId;
        // 检查累加器中是否已经存在该key的条目
        if (!accumulator[key]) {
          // 如果不存在，则创建一个新条目，并设置初始值
          accumulator[key] = {
            id: currentItem.examCourseId,
            examId: currentItem.examId,
            courseId: currentItem.courseId,
            examType: currentItem.examType,
            excellentScore: currentItem.excellentScore,
            goodScore: currentItem.goodScore,
            passScore: currentItem.passScore,
          };
        }
        return accumulator;
      }, {});
      this.examCourseData = Object.values(groupedData);
    },
    //课程成绩提交
    courseScoreSubmit() {
      this.submitLoading = true;
      enterExamCourseStudentScore(this.courseScoreData).then(() => {
        this.submitLoading = false;
        this.examScoreFlag = true;
        this.$message.success('保存成功！');
        this.getExamCourseScore();
        this.$emit('editScoreSuccess');
      }).catch(err => {
        console.log("err", err);
        this.submitLoading = false;
      })
    },
    //成绩表格学号，姓名，总成绩,是否通过列合并
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0 || columnIndex === 1 || columnIndex === 7 || columnIndex === 8) { // 添加了是否通过列的索引
        if (!this.spanMap) {
          this.calculateSpanMap(); // 确保合并行数已计算
        }
        const spanArr = this.spanMap[row.studentNo];
        if (spanArr) {
          if (rowIndex === spanArr[0]) {
            return [spanArr[1], 1]; // 返回合并的行数和列数（列数为1表示只合并行）
          } else {
            return [0, 0];
          }
        } else {
          return [1, 1]; // 如果没有找到匹配的学号，则默认不合并
        }
      } else {
        return [1, 1]; // 其他列默认不合并
      }
    },
    // 计算合并行数
    calculateSpanMap() {
      this.spanMap = {};
      let spanCount = 1;
      this.courseScoreData.forEach((item, index) => {
        if (!this.spanMap[item.studentNo]) {
          this.spanMap[item.studentNo] = [index, spanCount];
        } else {
          this.spanMap[item.studentNo][1]++;
        }
      });
    },
    // 导出表格
    exportTable(courseName) {
      try {
        if (!this.$refs.table || !this.$refs.table[0] || !this.courseScoreData) {
          console.error('表格或数据为空');
          return;
        }

        // 提取表头信息
        const columns = this.$refs.table[0].columns;
        const headers = columns.map(column => column.label);
        // 提取数据并处理可能的空值和格式化
        const data = this.courseScoreData.map(item => {
          return columns.map(column => {
            const value = item[column.property];
            if (value === undefined) {
              return '';
            }
            // 格式化考试类型
            if (column.property === 'examType') {
              return this.selectDictLabel(this.examTypeOpt, value)
            }
            // 格式化是否缺考
            if (column.property === 'missExam') {
              return value ? '是' : '否';
            }
            // 格式化是否通过
            if (column.property === 'isPassed') {
              return value ? '通过' : '未通过';
            }
            // 格式化成绩等级
            if (column.property === 'scoreGrade') {
              if (item.score >= item.excellentScore) {
                return '优秀';
              } else if (item.score >= item.goodScore) {
                return '良好';
              } else if (item.score >= item.passScore) {
                return '及格';
              } else {
                return '不及格';
              }
            }
            return value;
          });
        });

        // 创建合并单元格的配置
        const merges = [];
        let currentStudentNo = null;
        let startRow = 1; // 表头占用一行，所以从1开始
        let rowCount = 1;

        this.courseScoreData.forEach((item, index) => {
          if (item.studentNo !== currentStudentNo) {
            if (currentStudentNo !== null) {
              merges.push({ s: { r: startRow, c: 0 }, e: { r: startRow + rowCount - 1, c: 0 } }); // 学号
              merges.push({ s: { r: startRow, c: 1 }, e: { r: startRow + rowCount - 1, c: 1 } }); // 姓名
              merges.push({ s: { r: startRow, c: 7 }, e: { r: startRow + rowCount - 1, c: 7 } }); // 总成绩
              merges.push({ s: { r: startRow, c: 8 }, e: { r: startRow + rowCount - 1, c: 8 } }); // 是否通过
            }
            currentStudentNo = item.studentNo;
            startRow = index + 1; // +1 是因为表头占用一行
            rowCount = 1;
          } else {
            rowCount++;
          }
        });

        // 添加最后一组合并单元格
        if (currentStudentNo !== null) {
          merges.push({ s: { r: startRow, c: 0 }, e: { r: startRow + rowCount - 1, c: 0 } }); // 学号
          merges.push({ s: { r: startRow, c: 1 }, e: { r: startRow + rowCount - 1, c: 1 } }); // 姓名
          merges.push({ s: { r: startRow, c: 7 }, e: { r: startRow + rowCount - 1, c: 7 } }); // 总成绩
          merges.push({ s: { r: startRow, c: 8 }, e: { r: startRow + rowCount - 1, c: 8 } }); // 是否通过
        }

        // 创建工作表
        const worksheet = this.$XLSX.utils.aoa_to_sheet([headers, ...data]);
        worksheet['!merges'] = merges; // 添加合并单元格配置
        const workbook = this.$XLSX.utils.book_new();
        this.$XLSX.utils.book_append_sheet(workbook, worksheet, courseName);
        this.$XLSX.writeFile(workbook, '班级成绩.xlsx');
      } catch (error) {
        console.error('导出表格时发生错误:', error);
      }
    },
    //监听分数输入框变化
    validateScore(row) {
      // 确保分数输入为数字
      row.score = parseFloat(row.score);
      if (isNaN(row.score)) {
        row.score = 0;
      } else if (row.score < 0) {
        row.score = 0;
      } else if (row.score > 100) {
        row.score = 100;
      }
      // 重新计算总成绩
      this.calculateTotalScore();
    },
    //是否缺考字段变化
    handleMissExamChange(row) {
      if (row.missExam) {
        row.score = 0;
        // 调用 validateScore 方法来更新成绩等级和是否通过状态
        this.validateScore(row);
      } else {
        row.missExamDesc = '';
      }
    },
    //导入成绩
    uploadScore() {
      this.uploadDialog = true;
    },
    submitFileForm() {
      // 提交文件表单
      const file = this.$refs.upload.uploadFiles[0];
      if (!file) {
        this.$message.warning('请选择文件后再上传');
        return;
      }
      this.uploadDialog = false ;
      this.importFile = file.raw;
      this.readExcelFile(this.importFile);
    },
    // 解析导入的Excel文件并更新成绩数据
    readExcelFile(file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        const data = new Uint8Array(e.target.result);
        const workbook = this.$XLSX.read(data, { type: 'array' });
        const firstSheetName = workbook.SheetNames[0];
        const worksheet = workbook.Sheets[firstSheetName];
        const excelData = this.$XLSX.utils.sheet_to_json(worksheet, { header: 1 });
        this.updateScores(excelData);
      };
      reader.readAsArrayBuffer(file);
    },
    // 解析Excel数据为数组
    parseExcel(data) {
      const headers = data[0];
      const result = [];

      for (let i = 1; i < data.length; i++) {
        const obj = {};
        const currentline = data[i];

        for (let j = 0; j < headers.length; j++) {
          obj[headers[j]] = currentline[j];
        }
        result.push(obj);
      }
      return result;
    },
    // 更新成绩数据
    updateScores(data) {
      const parsedData = this.parseExcel(data);
      parsedData.forEach(item => {
        const student = this.courseScoreData.find(score => score.studentNo === item['学号'] && this.getExamTypeDict(score.examType) === item['考试类型']);
        if (student) {
          student.score = parseFloat(item['考试分数']);
          student.missExam = item['是否缺考'] === '是';
          student.missExamDesc = item['缺考说明'];
          this.validateScore(student);
        }
      });
      this.examScoreFlag = false;
    },
  }
}
</script>

<style scoped>

</style>
